home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1995 Free Software Foundation, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this software; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * As a special exception, the Free Software Foundation gives permission
- * for additional uses of the text contained in its release of GUILE.
- *
- * The exception is that, if you link the GUILE library with other files
- * to produce an executable, this does not by itself cause the
- * resulting executable to be covered by the GNU General Public License.
- * Your use of that executable is in no way restricted on account of
- * linking the GUILE library code into it.
- *
- * This exception does not however invalidate any other reasons why
- * the executable file might be covered by the GNU General Public License.
- *
- * This exception applies only to the code released by the
- * Free Software Foundation under the name GUILE. If you copy
- * code from other Free Software Foundation releases into a copy of
- * GUILE, as the General Public License permits, the exception does
- * not apply to the code that you add in this way. To avoid misleading
- * anyone as to the status of such modified files, you must delete
- * this exception notice from them.
- *
- * If you write modifications of your own for GUILE, it is your choice
- * whether to permit this exception to apply to your modifications.
- * If you do not wish that, delete this exception notice.
- */
-
-
- #include <stdio.h>
- #include "_scm.h"
-
-
-
-
- /* {Errors and Exceptional Conditions}
- */
-
-
- SCM scm_err_exp = SCM_UNDEFINED;
- SCM scm_err_env = SCM_UNDEFINED;
- char * scm_err_pos = "you lose (internal error)";
- char * scm_err_s_subr = "you lose (internal error)";
- scm_cell scm_tmp_errobj = {(SCM) SCM_UNDEFINED, (SCM) EOL};
- SCM *scm_loc_errobj = (SCM *) & scm_tmp_errobj;
- SCM system_error_sym;
-
- struct errdesc scm_errmsgs[] =
- {
- {"Wrong number of args", 0, 0},
- {"numerical overflow", 0, FPE_SIGNAL},
- {"Argument out of range", 0, FPE_SIGNAL},
- {"Could not allocate", "out-of-storage", 0},
- {"EXIT", "end-of-program", -1},
- {"hang up", "hang-up", EXIT},
- {"user interrupt", "user-interrupt", 0},
- {"arithmetic error", "arithmetic-error", 0},
- {"bus error", 0, 0},
- {"segment violation", 0, 0},
- {"alarm", "alarm-interrupt", 0}
- };
-
- /* True only when errors indicate a bug in the
- * interpreter.
- */
- int scm_errjmp_bad = 1;
-
- /* True between DEFER_INTS and ALLOW_INTS, and
- * when the interpreter is not running at all.
- */
- int scm_ints_disabled = 1;
-
- /* Becomes true between DEFER_INTS and ALLOW_INTS if a
- * a signal occurs. Cleared by ALLOW_INTS which handles
- * the signal.
- */
- int scm_sig_deferred = 0;
-
- /* Becomes true between DEFER_INTS and ALLOW_INTS if a
- * an alarm signal occurs. Cleared by ALLOW_INTS which handles
- * the signal.
- */
- int scm_alrm_deferred = 0;
-
- /* Handle signal number I.
- * If a scheme handler is allowed for this signal,
- * and the user has defined one, call it and
- * return i.
- *
- * Otherwise, if there is a more basic signal whose
- * handler is applicable, return that signal number.
- *
- * Otherwise return 0.
- */
- #ifdef __STDC__
- static int
- scm_handle_it (int i)
- #else
- static int
- scm_handle_it (i)
- int i;
- #endif
- {
- char *name;
- SCM proc;
-
- name = scm_errmsgs[i - WNA].s_response;
- if (scm_errjmp_bad) return -1;
- if (name)
- {
- NEWCELL(proc); /* discard possibly-used cell */
- proc = CDR (scm_intern (name, (sizet) strlen (name)));
- if (NIMP (proc))
- {
- scm_apply (proc, EOL, EOL);
- return i;
- }
- }
- return scm_errmsgs[i - WNA].parent_err;
- }
-
- #ifdef __STDC__
- void
- scm_han_sig (void)
- #else
- void
- scm_han_sig ()
- #endif
- {
- scm_sig_deferred = 0;
- if (INT_SIGNAL != scm_handle_it (INT_SIGNAL))
- scm_wta (SCM_UNDEFINED, (char *) INT_SIGNAL, "");
- }
-
- #ifdef __STDC__
- void
- scm_han_alrm (void)
- #else
- void
- scm_han_alrm ()
- #endif
- {
- scm_alrm_deferred = 0;
- if (ALRM_SIGNAL != scm_handle_it (ALRM_SIGNAL))
- scm_wta (SCM_UNDEFINED, (char *) ALRM_SIGNAL, "");
- }
-
- extern int errno;
- #ifdef __STDC__
- static void
- err_head (char *str)
- #else
- static void
- err_head (str)
- char *str;
- #endif
- {
- int oerrno = errno;
- scm_exitval = MAKINUM (EXIT_FAILURE);
- if (NIMP (cur_outp))
- scm_fflush (cur_outp);
- scm_putc ('\n', cur_errp);
- if (BOOL_F != *scm_loc_loadpath)
- {
- scm_iprin1 (*scm_loc_loadpath, cur_errp, 1);
- scm_puts (", line ", cur_errp);
- scm_intprint ((long) scm_linum, 10, cur_errp);
- scm_puts (": ", cur_errp);
- }
- scm_fflush (cur_errp);
- errno = oerrno;
- if (cur_errp == def_errp)
- {
- if (errno > 0)
- perror (str);
- fflush (stderr);
- return;
- }
- }
-
- #ifdef __STDC__
- void
- scm_warn (char *str1, char *str2)
- #else
- void
- scm_warn (str1, str2)
- char *str1;
- char *str2;
- #endif
- {
- err_head ("WARNING");
- scm_puts ("WARNING: ", cur_errp);
- scm_puts (str1, cur_errp);
- scm_puts (str2, cur_errp);
- scm_putc ('\n', cur_errp);
- scm_fflush (cur_errp);
- }
-
-
- PROC (s_errno, "errno", 0, 1, 0, scm_errno);
- #ifdef __STDC__
- SCM
- scm_errno (SCM arg)
- #else
- SCM
- scm_errno (arg)
- SCM arg;
- #endif
- {
- int old = errno;
- if (!UNBNDP (arg))
- {
- if (FALSEP (arg))
- errno = 0;
- else
- errno = INUM (arg);
- }
- return MAKINUM (old);
- }
-
- PROC (s_perror, "perror", 1, 0, 0, scm_perror);
- #ifdef __STDC__
- SCM
- scm_perror (SCM arg)
- #else
- SCM
- scm_perror (arg)
- SCM arg;
- #endif
- {
- ASSERT (NIMP (arg) && STRINGP (arg), arg, ARG1, s_perror);
- err_head (CHARS (arg));
- return UNSPECIFIED;
- }
-
- #ifdef __STDC__
- void
- def_err_response (void)
- #else
- void
- def_err_response ()
- #endif
- {
- SCM obj = *scm_loc_errobj;
- DEFER_INTS;
- err_head ("ERROR");
- scm_puts ("ERROR: ", cur_errp);
- if (scm_err_s_subr && *scm_err_s_subr)
- {
- scm_puts (scm_err_s_subr, cur_errp);
- scm_puts (": ", cur_errp);
- }
- if (scm_err_pos == (char *) ARG1 && UNBNDP (*scm_loc_errobj))
- scm_err_pos = (char *) WNA;
- #ifdef nosve
- if ((~0x1fL) & (short) scm_err_pos)
- scm_puts (scm_err_pos, cur_errp);
- else if (WNA > (short) scm_err_pos)
- {
- scm_puts ("Wrong type in arg", cur_errp);
- scm_putc('0'+(int)scm_err_pos, cur_errp);
- }
- #else
- if ((~0x1fL) & (long) scm_err_pos)
- scm_puts (scm_err_pos, cur_errp);
- else if (WNA > (long) scm_err_pos)
- {
- scm_puts ("Wrong type in arg", cur_errp);
- scm_putc(scm_err_pos ? '0'+(int)scm_err_pos : ' ', cur_errp);
- }
- #endif
- else
- {
- scm_puts (scm_errmsgs[((int) scm_err_pos) - WNA].msg, cur_errp);
- goto outobj;
- }
- if (IMP (obj) || SYMBOLP (obj) || (TYP16 (obj) == tc7_port)
- || (NFALSEP (scm_procedure_p (obj))) || (NFALSEP (scm_number_p (obj))))
- {
- outobj:
- if (!UNBNDP (obj))
- {
- scm_puts (((long) scm_err_pos == WNA) ? " to " : " ", cur_errp);
- scm_iprin1 (obj, cur_errp, 1);
- }
- }
- else
- scm_puts (" (see errobj)", cur_errp);
- if (UNBNDP (scm_err_exp))
- goto getout;
- if (NIMP (scm_err_exp))
- {
- scm_puts ("\n; in expression: ", cur_errp);
- if (NCONSP (scm_err_exp))
- scm_iprin1 (scm_err_exp, cur_errp, 1);
- else if (SCM_UNDEFINED == CDR (scm_err_exp))
- scm_iprin1 (CAR (scm_err_exp), cur_errp, 1);
- else
- scm_iprlist ("(... ", scm_err_exp, ')', cur_errp, 1);
- }
- if (NULLP (scm_err_env) || (BOOL_T == scm_procedure_p (CAR (scm_err_env))))
- scm_puts ("\n; in top level environment.", cur_errp);
- else
- {
- SCM env = scm_err_env;
- scm_puts ("\n; in scope:", cur_errp);
- while (NNULLP (env) && (BOOL_T != scm_procedure_p (CAR(env))))
- {
- scm_putc ('\n', cur_errp);
- scm_puts ("; ", cur_errp);
- scm_iprin1 (CAR (CAR (env)), cur_errp, 1);
- env = CDR (env);
- }
- }
- getout:
- scm_putc ('\n', cur_errp);
- scm_fflush (cur_errp);
- scm_err_exp = scm_err_env = SCM_UNDEFINED;
- if (scm_errjmp_bad)
- {
- scm_iprin1 (obj, cur_errp, 1);
- scm_puts ("\nFATAL ERROR DURING CRITICAL CODE SECTION\n", cur_errp);
- #ifdef vms
- exit(EXIT_FAILURE);
- #else
- exit(errno? (long)errno : EXIT_FAILURE);
- #endif
- }
- errno = 0;
- ALLOW_INTS;
- }
-
-
-
- #ifdef __STDC__
- void
- scm_everr (SCM exp, SCM env, SCM arg, char *pos, char *s_subr)
- #else
- void
- scm_everr (exp, env, arg, pos, s_subr)
- SCM exp;
- SCM env;
- SCM arg;
- char *pos;
- char *s_subr;
- #endif
- {
-
- /* Give preference to a user supplied error
- * handler.
- */
- {
- SCM desc;
- SCM args;
-
- if ((~0x1fL) & (long) pos)
- {
- desc = makfrom0str (pos);
- }
- else
- desc = MAKINUM ((long)pos);
-
- {
- SCM sym;
- if (!s_subr || !*s_subr)
- sym = BOOL_F;
- else
- sym = CAR (scm_intern0 (s_subr));
- args = scm_listify (desc, sym, arg, SCM_UNDEFINED);
- }
-
- /* (throw (quote system-error) <desc> <proc-name> arg)
- *
- * <desc> is a string or an integer (see %%system-errors).
- * <proc-name> is a symbol or #f in some annoying cases (e.g. cddr).
- */
-
- _scm_throw (system_error_sym, args, 0);
-
- /* The call to throw might return if no handler can
- * be found.
- */
- }
-
- /* Handle the error at the current root continuation. */
- scm_err_exp = exp;
- scm_err_env = env;
- *scm_loc_errobj = arg;
- scm_err_pos = pos;
- scm_err_s_subr = s_subr;
- if ( ((~0x1fL) & (long) pos)
- || (WNA > (long) pos)
- || NIMP(dynwinds)
- || scm_errjmp_bad)
- {
- def_err_response ();
- scm_abort ();
- }
- if (scm_errjmp_bad)
- exit (INUM (scm_exitval));
- scm_dowinds (EOL, scm_ilength (dynwinds));
- longjmp (JMPBUF (rootcont), (int) pos);
- /* Error processing is done at the stack base. */
- }
-
- #ifdef __STDC__
- SCM
- scm_wta (SCM arg, char *pos, char *s_subr)
- #else
- SCM
- scm_wta (arg, pos, s_subr)
- SCM arg;
- char *pos;
- char *s_subr;
- #endif
- {
- scm_everr (SCM_UNDEFINED, EOL, arg, pos, s_subr);
- return UNSPECIFIED;
- }
-
-
-
- #ifdef __STDC__
- void
- scm_init_error (void)
- #else
- void
- scm_init_error ()
- #endif
- {
- #include "error.x"
- }
-
-